﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Hardcodet.Wpf.TaskbarNotification;
using System.Windows.Controls.Primitives;
using System.Diagnostics;
using System.Collections;
using Gma.UserActivityMonitor;

namespace eStream.Helpdesk.Notifier
{
    /// <summary>
    /// Interaction logic for NotificationPopup.xaml
    /// </summary>
    public partial class NotificationPopup : UserControl
    {
        NotifierSettings settings = new NotifierSettings();

        private bool isClosing = false;
        private bool closeTimerStarted = false;
        TaskbarIcon taskbarIcon;

        public NotificationPopup()
        {
            InitializeComponent();
            TaskbarIcon.AddBalloonShowedHandler(this, OnBalloonShowed);
            TaskbarIcon.AddBalloonClosingHandler(this, OnBalloonClosing);
        }

        #region TicketSource dependency property

        public IEnumerable<Ticket> TicketSource
        {
            get { return GetValue(TicketSourceProperty) as IEnumerable<Ticket>; }
            set { SetValue(TicketSourceProperty, value); }
        }

        public static readonly DependencyProperty TicketSourceProperty =
            DependencyProperty.Register(
                "TicketSource",
                typeof(IEnumerable<Ticket>),
                typeof(NotificationPopup),
                new PropertyMetadata(null, OnTicketSourcePropertyChanged));

        private static void OnTicketSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var popup = (NotificationPopup)d;
            var tickets = ((IEnumerable<Ticket>)e.NewValue);
            var ticketsCount = tickets.Count();
            if (ticketsCount > 0)
            {
                popup.LastTicketNumber = ticketsCount;
                popup.CurrentTicketNumber = 1;
            }
        }

        #endregion

        #region CurrentTicket dependency property

        /// <summary>
        /// Description
        /// </summary>
        public static readonly DependencyProperty CurrentTicketProperty =
            DependencyProperty.Register("CurrentTicket",
                                        typeof(Ticket),
                                        typeof(NotificationPopup),
                                        new FrameworkPropertyMetadata(null));

        /// <summary>
        /// A property wrapper for the <see cref="TicketSubjectProperty"/>
        /// dependency property:<br/>
        /// Description
        /// </summary>
        public Ticket CurrentTicket
        {
            get { return (Ticket)GetValue(CurrentTicketProperty); }
            set { SetValue(CurrentTicketProperty, value); }
        }

        #endregion

        #region CurrentTicketNumber dependency property

        /// <summary>
        /// Description
        /// </summary>
        public static readonly DependencyProperty CurrentTicketNumberProperty =
            DependencyProperty.Register("CurrentTicketNumber",
                                        typeof(int),
                                        typeof(NotificationPopup),
                                        new FrameworkPropertyMetadata(0, OnCurrentTicketNumberChanged));

        /// <summary>
        /// A property wrapper for the <see cref="CurrentTicketNumberProperty"/>
        /// dependency property:<br/>
        /// Description
        /// </summary>
        public int CurrentTicketNumber
        {
            get { return (int)GetValue(CurrentTicketNumberProperty); }
            set { SetValue(CurrentTicketNumberProperty, value); }
        }

        private static void OnCurrentTicketNumberChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var popup = (NotificationPopup)d;
            var ticketNumber = ((int)e.NewValue);

            popup.CurrentTicket = popup.TicketSource.ElementAt(ticketNumber - 1);
        }
        #endregion

        #region LastTicketNumber dependency property

        /// <summary>
        /// Description
        /// </summary>
        public static readonly DependencyProperty LastTicketNumberProperty =
            DependencyProperty.Register("LastTicketNumber",
                                        typeof(int),
                                        typeof(NotificationPopup),
                                        new FrameworkPropertyMetadata(1));

        /// <summary>
        /// A property wrapper for the <see cref="LastTicketNumberProperty"/>
        /// dependency property:<br/>
        /// Description
        /// </summary>
        public int LastTicketNumber
        {
            get { return (int)GetValue(LastTicketNumberProperty); }
            set { SetValue(LastTicketNumberProperty, value); }
        }

        #endregion


        private void OnBalloonShowed(object sender, RoutedEventArgs e)
        {
            // attach global hooks to detect user activity
            HookManager.MouseMove += HookManager_MouseEvent;
            HookManager.MouseDown += HookManager_MouseEvent;

            HookManager.KeyDown += HookManager_KeyDown;

            //suppress hiding the balloon until some user activity is present
            taskbarIcon = TaskbarIcon.GetParentTaskbarIcon(this);
            taskbarIcon.ResetBalloonCloseTimer();
        }

        /// <summary>
        /// By subscribing to the <see cref="TaskbarIcon.BalloonClosingEvent"/>
        /// and setting the "Handled" property to true, we suppress the popup
        /// from being closed in order to display the fade-out animation.
        /// </summary>
        private void OnBalloonClosing(object sender, RoutedEventArgs e)
        {
            isClosing = true;

            HookManager.MouseMove -= HookManager_MouseEvent;
            HookManager.MouseDown -= HookManager_MouseEvent;

            HookManager.KeyDown -= HookManager_KeyDown;
        }


        /// <summary>
        /// Resolves the <see cref="TaskbarIcon"/> that displayed
        /// the balloon and requests a close action.
        /// </summary>
        private void imgClose_MouseDown(object sender, MouseButtonEventArgs e)
        {
            //the tray icon assigned this attached property to simplify access
            taskbarIcon.CloseBalloon();
            e.Handled = true;
        }

        /// <summary>
        /// If the users hovers over the balloon, we don't close it.
        /// </summary>
        private void grid_MouseEnter(object sender, MouseEventArgs e)
        {
            //if we're already running the fade-out animation, do not interrupt anymore
            //(makes things too complicated for the sample)
            if (isClosing) return;

            //the tray icon assigned this attached property to simplify access
            taskbarIcon.ResetBalloonCloseTimer();
        }


        private void grid_MouseLeave(object sender, MouseEventArgs e)
        {
            if (isClosing)
                return;

            taskbarIcon.ResetBalloonCloseTimer(true);
        }


        /// <summary>
        /// Closes the popup once the fade-out animation completed.
        /// The animation was triggered in XAML through the attached
        /// BalloonClosing event.
        /// </summary>
        private void OnFadeOutCompleted(object sender, EventArgs e)
        {
            Popup pp = (Popup)Parent;
            pp.IsOpen = false;
        }


        private void imgPrevious_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (CurrentTicketNumber > 1)
            {
                --CurrentTicketNumber;
            }
        }

        private void imgNext_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (CurrentTicketNumber < LastTicketNumber)
            {
                ++CurrentTicketNumber;
            }
        }

        private void Ticket_MouseDown(object sender, MouseButtonEventArgs e)
        {
            var uri = new Uri(new Uri(settings.HelpdeskAddress), String.Format("/tickets/{0}", CurrentTicket.ID));
            Process.Start(uri.ToString());
        }

        /// <summary>
        /// Starts balloon's close timer
        /// </summary>
        private void StartCloseTimer()
        {
            if (!closeTimerStarted)
            {
                closeTimerStarted = true;
                taskbarIcon.ResetBalloonCloseTimer(true);
            }
        }

        void HookManager_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            StartCloseTimer();
        }

        void HookManager_MouseEvent(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            StartCloseTimer();
        }

    }
}
